package test;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.resource.ResourceCollection;
import org.eclipse.jetty.webapp.WebAppClassLoader;
import org.eclipse.jetty.webapp.WebAppContext;

/**
 * @Title: Jettys.java
 * @Package cn.thinjoy.xyy.zhbd.test.jetty
 * @Description: Jetty工具类
 * @Date 2014-2-20-上午11:21:51
 * @Author: qizai
 * @Version: V1.0.0
 */
public class JettyKit {

	public static JettyKit kit = new JettyKit();

	private static final String DEFAULT_WEBAPP_PATH = "src/main/webapp";
	public static final String ACTIVE_PROFILE = "spring.profiles.active";
	public static final String DEFAULT_PROFILE = "spring.profiles.default";
	public static final String PRODUCTION = "production";
	public static final String DEVELOPMENT = "development";
	public static final String UNIT_TEST = "test";
	public static final String FUNCTIONAL_TEST = "functional";

	private static String profile = UNIT_TEST;
	private static int port = 8080;
	private static String context = "/demo";
	private JettyKit() {
	}

	private static void info() {
		System.out.println("[INFO] 运行环境为:" + profile);
		System.out.println("[INFO] 服务地址: http://localhost:" + port + context);
		System.out.println("[HINT] 按回车键重新启动服务.");
		System.out.println("[HINT] 按k+回车键停止服务.");
	}
	/**
	 * 设置运行环境，默认为test
	 * 
	 * @param profile
	 * @return
	 */
	public JettyKit env(String profile) {
		JettyKit.profile = profile;
		return this;
	}
	/**
	 * 使用默认8080端口运行
	 * 
	 * @param context
	 *            例如：/demo
	 */
	public void start(String context) {
		start(JettyKit.port, context);
	}
	/**
	 * 
	 * @param port
	 * @param context
	 *            例如：/demo
	 */
	public void start(int port, String context) {
		JettyKit.port = port;
		JettyKit.context = context;

		setProfileAsSystemProperty(JettyKit.profile);

		Server server = createServerInSource(JettyKit.port, JettyKit.context);
		try {
			server.start();
			info();
			// 等待用户输入回车重载应用.
			while (true) {
				int c = System.in.read();
				if (107 == c) {// k
					stopServer(server);
					System.exit(-1);
					break;
				}
				if (c == '\n') {
					reloadContext(server);
					info();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}

	/**
	 * 在Spring启动前，设置profile的环境变量。
	 */
	private static void setProfileAsSystemProperty(String profile) {
		System.setProperty(ACTIVE_PROFILE, profile);
	}

	/**
	 * 创建用于开发运行调试的Jetty Server, 以src/main/webapp为Web应用目录.
	 */
	private static Server createServerInSource(int port, String contextPath) {
		Server server = new Server(port);
		// 设置在JVM退出时关闭Jetty的钩子。
		server.setStopAtShutdown(true);
		// configure and start it
		server.setHandler(createWebAppContext(DEFAULT_WEBAPP_PATH, contextPath));
		return server;
	}

	private static WebAppContext createWebAppContext(String rootDir, String webContext) {
		WebAppContext context = new WebAppContext();
		context.setContextPath(webContext);
		context.setBaseResource(new ResourceCollection(new String[]{rootDir}));
		return context;
	}
	/**
	 * 快速重新启动application，重载target/classes与target/test-classes.
	 */
	private static void reloadContext(Server server) throws Exception {
		WebAppContext context = (WebAppContext) server.getHandler();

		System.out.println("[INFO] 重启服务.");
		context.stop();

		WebAppClassLoader classLoader = new WebAppClassLoader(context);
		classLoader.addClassPath("target/classes");
		classLoader.addClassPath("target/test-classes");
		context.setClassLoader(classLoader);

		context.start();

		System.out.println("[INFO] 重启服务完成.");
	}

	private static void stopServer(Server server) throws Exception {
		WebAppContext context = (WebAppContext) server.getHandler();
		System.out.println("[INFO] 停止服务.");

		context.stop();
		server.stop();

		System.out.println("[INFO] 停止服务完成.");
	}
}
